]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
AppDisplay: don't show a "New Window" menu item if not possible
authorGiovanni Campagna <gcampagna@src.gnome.org>
Sun, 19 Jan 2014 17:05:16 +0000 (18:05 +0100)
committerGiovanni Campagna <gcampagna@src.gnome.org>
Fri, 1 Aug 2014 09:45:18 +0000 (11:45 +0200)
If the application reports itself as single window (through
an explicit indication in the desktop file or some heuristics),
not show a "New window" item that doesn't actually open a new window.

https://bugzilla.gnome.org/show_bug.cgi?id=722554

js/ui/appDisplay.js
src/shell-app.c
src/shell-app.h

index 524635c94c4ac15459d803047dac6e644c16d3bd..253d4c40656995eec249ef373359f804a0cabfa7 100644 (file)
@@ -1628,12 +1628,14 @@ const AppIconMenu = new Lang.Class({
         if (!this._source.app.is_window_backed()) {
             this._appendSeparator();
 
-            this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
-            this._newWindowMenuItem.connect('activate', Lang.bind(this, function() {
-                this._source.app.open_new_window(-1);
-                this.emit('activate-window', null);
-            }));
-            this._appendSeparator();
+            if (this._source.app.can_open_new_window()) {
+                this._newWindowMenuItem = this._appendMenuItem(_("New Window"));
+                this._newWindowMenuItem.connect('activate', Lang.bind(this, function() {
+                    this._source.app.open_new_window(-1);
+                    this.emit('activate-window', null);
+                }));
+                this._appendSeparator();
+            }
 
             let appInfo = this._source.app.get_app_info();
             let actions = appInfo.list_actions();
index 65290252b5d05f5099d3cf9e87172f495530a9d4..47146961b24e8367d24e9cba1bff8cd88c1417ed 100644 (file)
@@ -705,6 +705,72 @@ shell_app_open_new_window (ShellApp      *app,
   shell_app_launch (app, 0, workspace, NULL);
 }
 
+/**
+ * shell_app_can_open_new_window:
+ * @app: a #ShellApp
+ *
+ * Returns %TRUE if the app supports opening a new window through
+ * shell_app_open_new_window() (ie, if calling that function will
+ * result in actually opening a new window and not something else,
+ * like presenting the most recently active one)
+ */
+gboolean
+shell_app_can_open_new_window (ShellApp *app)
+{
+  ShellAppRunningState *state;
+
+  /* Apps that are not running can always open new windows, because
+     activating them would open the first one */
+  if (!app->running_state)
+    return TRUE;
+
+  state = app->running_state;
+
+  /* If the app has an explicit new-window action, then it can
+
+     (or it should be able to - we don't actually call the action
+     because we need to trigger startup notification, so it still
+     depends on what the app decides to do for Activate vs ActivateAction)
+  */
+  if (g_action_group_has_action (G_ACTION_GROUP (state->muxer), "app.new-window"))
+    return TRUE;
+
+  /* If the app doesn't have a desktop file, then nothing is possible */
+  if (!app->info)
+    return FALSE;
+
+  /* If the app is explicitly telling us, then we know for sure */
+  if (g_desktop_app_info_has_key (G_DESKTOP_APP_INFO (app->info),
+                                  "X-GNOME-SingleWindow"))
+    return !g_desktop_app_info_get_boolean (G_DESKTOP_APP_INFO (app->info),
+                                            "X-GNOME-SingleWindow");
+
+  /* If this is a unique GtkApplication, and we don't have a new-window, then
+     probably we can't
+
+     We don't consider non-unique GtkApplications here to handle cases like
+     evince, which don't export a new-window action because each window is in
+     a different process. In any case, in a non-unique GtkApplication each
+     Activate() knows nothing about the other instances, so it will show a
+     new window.
+  */
+  if (state->remote_menu)
+    {
+      const char *application_id;
+      application_id = meta_window_get_gtk_application_id (state->windows->data);
+      if (application_id != NULL)
+        return FALSE;
+      else
+        return TRUE;
+    }
+
+  /* In all other cases, we don't have a reliable source of information
+     or a decent heuristic, so we err on the compatibility side and say
+     yes.
+  */
+  return TRUE;
+}
+
 /**
  * shell_app_get_state:
  * @app: a #ShellApp
index 120385c4ea1980fb6b987a8eab9a72945ee8aa6c..4cf7572867885aecfb0e64dd771d63aa82fffd66 100644 (file)
@@ -56,6 +56,7 @@ void shell_app_activate_full (ShellApp      *app,
 
 void shell_app_open_new_window (ShellApp *app,
                                 int       workspace);
+gboolean shell_app_can_open_new_window (ShellApp *app);
 
 ShellAppState shell_app_get_state (ShellApp *app);